package com.one.blocks.eds.config;

import com.one.blocks.eds.aop.EdsAspect;
import com.one.blocks.eds.config.properties.EdsProperties;
import com.one.blocks.eds.core.EdsPropertiesLoader;
import com.one.blocks.eds.core.ExpireDataSource;
import com.one.blocks.eds.core.ExpireDataSourceManager;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

import javax.sql.DataSource;

/**
 * @author <a href="mailto:idler41@163.con">linfuxin</a> created on 2023-09-11 10:05:12
 */
@Configuration
@ConditionalOnMissingBean(DataSource.class)
@AutoConfigureBefore({DataSourceAutoConfiguration.class})
@EnableConfigurationProperties({EdsProperties.class})
public class EdsAutoConfig {

    @Bean
    @ConditionalOnProperty(prefix = "spring.datasource.eds.aop", name = "enable", havingValue = "true", matchIfMissing = true)
    public EdsAspect edsAspect() {
        return new EdsAspect();
    }

    @Bean
    @ConditionalOnMissingBean(EdsPropertiesLoader.class)
    public EdsPropertiesLoader defaultFunction() {
        return key -> {
            throw new UnsupportedOperationException();
        };
    }

    @Bean
    @ConditionalOnMissingBean(ExpireDataSource.class)
    public ExpireDataSource expireDataSource(
            @Lazy EdsPropertiesLoader defaultFunction,
            EdsProperties dataSourceProperties
    ) {
        return new ExpireDataSource(defaultFunction, dataSourceProperties);
    }

    @Bean
    @ConditionalOnBean(ExpireDataSource.class)
    public ExpireDataSourceManager expireDataSourceManager(ExpireDataSource expireDataSource) {
        return new ExpireDataSourceManager(expireDataSource);
    }
}
